package com.ansion.basedb.dao.entity;

import android.content.ContentValues;
import android.text.TextUtils;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;


import com.ansion.basedb.database.SqlDBInterface;
import com.ansion.basedb.database.sql.SQLField;
import com.ansion.basedb.database.sql.SQLRow;
import com.ansion.basedb.database.sql.SQLTable;
import com.ansion.basedb.storage.DisplayNameUtil;
import com.ansion.constant.BConstant;
import com.ansion.log.S;
import com.ansion.string.StringUtils;
import com.ansion.utils.ContactUtil;

import org.json.JSONObject;

import java.util.Objects;

/**
 * created by zhaoyuntao
 * on 25/01/2024
 * FtsUer只存一份元数据
 */
public class FtsUserEntity implements SqlDBInterface {
    @IntDef({
            UserType.TYPE_DEFAULT,
            UserType.TYPE_CONTACT,
    })
    public @interface UserType {
        int TYPE_DEFAULT = 0;
        int TYPE_CONTACT = 1;
    }

    private String uid;
    //存个int类型，便于后续扩展
    private int type = UserType.TYPE_DEFAULT;//1是联系人，0不是联系人
    private String nickName;
    private String firstName;
    private String lastName;
    private String middleName;
    private String formatPhone;

    /**
     * 内存字段
     */
    private long rowId;


    @Override
    public SQLTable getTable() {
        return new SQLTable(UserTables.FTS_USER.TABLE_NAME, BConstant.MIGRATE.VERSION_CODE_DB)
                .fts(false)
                .addField(new SQLField(UserTables.FTS_USER.KEY_CONTENT).index(true))
                .addField(new SQLField(UserTables.FTS_USER.KEY_UID))
                .addField(new SQLField(UserTables.FTS_USER.KEY_TYPE))
                .addField(new SQLField(UserTables.FTS_USER.KEY_EXTRA))
                .addField(new SQLField(UserTables.FTS_USER.KEY_EXTRA1))
                .addField(new SQLField(UserTables.FTS_USER.KEY_EXTRA2))
                .addField(new SQLField(UserTables.FTS_USER.KEY_EXTRA3))
                .addField(new SQLField(UserTables.FTS_USER.KEY_EXTRA4))
                .addField(new SQLField(UserTables.FTS_USER.KEY_EXTRA5));
    }

    @Override

    public @NonNull SQLRow writeToSQLRow() {
        return new SQLRow().put(getContentValues());
    }

    @Override
    public void readFromSQLRow(@NonNull SQLRow row) {
        uid = row.getAsString(UserTables.FTS_USER.KEY_UID);
        type = row.getAsInteger(UserTables.FTS_USER.KEY_TYPE);
        readExtraJson(row.getAsString(UserTables.FTS_USER.KEY_EXTRA));
    }

    public ContentValues getContentValues() {
        ContentValues values = new ContentValues();
        if (TextUtils.isEmpty(formatPhone))
            formatPhone = ContactUtil.getFormatPhone(uid);
        if (rowId > 0) {
            values.put(BConstant.MIGRATE.KEY_ROW_ID, rowId);
        }
        values.put(UserTables.FTS_USER.KEY_UID, uid);
        values.put(UserTables.FTS_USER.KEY_TYPE, type);
        values.put(UserTables.FTS_USER.KEY_CONTENT, generateContent());
        values.put(UserTables.FTS_USER.KEY_EXTRA, generateExtraJson());
        return values;
    }


    private String generateContent() {
        return StringUtils.generateFTSContent(getDisplayName(),
                uid, formatPhone
        );
    }

    @NonNull
    public String generateExtraJson() {
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("nickName", nickName);
            jsonObject.put("firstName", firstName);
            jsonObject.put("middleName", middleName);
            jsonObject.put("lastName", lastName);
            jsonObject.put("formatPhone", formatPhone);
        } catch (Throwable e) {
            S.e(e);
        }
        return jsonObject.toString();
    }

    public void readExtraJson(String extra) {
        try {
            JSONObject jsonObject = new JSONObject(extra);
            nickName = jsonObject.optString("nickName");
            firstName = jsonObject.optString("firstName");
            middleName = jsonObject.optString("middleName");
            lastName = jsonObject.optString("lastName");
            formatPhone = jsonObject.optString("formatPhone");
        } catch (Throwable e) {
            S.e(e);
        }
    }


    public FtsUserEntity set(String uid, boolean isContact, String nickname, String firstName, String middleName, String lastName) {
        this.uid = uid;
        this.type = isContact ? UserType.TYPE_CONTACT : UserType.TYPE_DEFAULT;
        this.nickName = nickname;
        this.firstName = firstName;
        this.lastName = lastName;
        this.middleName = middleName;
        return this;
    }

    public FtsUserEntity setUid(String uid) {
        this.uid = uid;
        return this;
    }

    public FtsUserEntity setRowId(long rowId) {
        this.rowId = rowId;
        return this;
    }

    public FtsUserEntity setType(int type) {
        this.type = type;
        return this;
    }


    public FtsUserEntity setNickName(String nickName) {
        this.nickName = nickName;
        return this;
    }

    public FtsUserEntity set(String firstName, String middleName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.middleName = middleName;
        return this;
    }

    public String getDisplayName() {
        return DisplayNameUtil.getDisplayName(uid, nickName, type == UserType.TYPE_CONTACT, firstName, middleName, lastName, true);
    }

    public String getUid() {
        return uid;
    }

    public int getType() {
        return type;
    }

    public String getNickName() {
        return nickName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getFormatPhone() {
        return formatPhone;
    }

    public long getRowId() {
        return rowId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FtsUserEntity that = (FtsUserEntity) o;
        return Objects.equals(uid, that.uid);
    }

    @Override
    public int hashCode() {
        return Objects.hash(uid);
    }

    @NonNull
    @Override
    public String toString() {
        return uid;
    }

    public boolean contentIsSame(FtsUserEntity other) {
        return StringUtils.stringIsEqualIgnoreNullOrEmpty(uid, other.getUid()) && StringUtils.stringIsEqualIgnoreNullOrEmpty(nickName, other.getNickName())
                && type == other.getType() && StringUtils.stringIsEqualIgnoreNullOrEmpty(firstName, other.getFirstName()) &&
                StringUtils.stringIsEqualIgnoreNullOrEmpty(middleName, other.getMiddleName()) && StringUtils.stringIsEqualIgnoreNullOrEmpty(lastName, other.getLastName())
                ;
    }

}
